'''
Created on 10/08/2009

@author: eh01
'''

# Imports
#
from xml.etree import ElementTree
from zipfile import ZipFile
import base64
import os
import unittest

from datastore import database
from datastore.database import DataStore
from datastore.resource import DeserialisationException, Resource
from datastore.uri import Uri
from package import manager
from package.manager import BadYarraPackageException, XMLFormatException
from package.manager import PackageManager
from package.pkge import Package


class ManagerTest(unittest.TestCase):


    def setUp(self):
        pass


    def tearDown(self):
        pass

#    def test_download_file_case_1(self):
#        '''[manager] test download file file exists'''
#        try:
#            test_file_content = "Hello. This is\na test of a file to\nbe read."
#            cur_dir = os.getcwd()
#            path_to_file = cur_dir + '\\test.file'
#            file1 = open(path_to_file, "wb")
#            file1.write(test_file_content)
#            file1.close()
#            url = 'file:///{0}'.format(path_to_file)
#            file2 = PackageManager().download_file(url)
#            content_as_string = file2.read()
#            file2.close()
#            if test_file_content == content_as_string:
#                assert True
#            else:
#                self.fail('download failed')
#        finally:
#            os.remove(path_to_file)
#
#    def test_download_file_case_2(self):
#        '''[manager] test download file file doesnt exists'''
#        cur_dir = os.getcwd()
#        path_to_file = cur_dir + '\\test.file'
#        url = 'file:///{0}'.format(path_to_file)
#        try:
#            file = PackageManager().download_file(url)
#            self.fail('should not be able to find file')
#        except IOError:
#            assert True
#    
#    def test_get_resource_from_zip_case_1(self):
#        '''[manager] test get zip content with correctly serialised resources'''
#        test_string = "HELLO WORLD"
#        rs = Resource()
#        rs.content = test_string
#        file_name = 'testfile'
#        zip_file_name = 'test.zip'
#        encoded_test_string = base64.encodestring(test_string)
#        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><resource xmlns="http://yarra-project.com/element/"><content><item key="content" type="yarra:type/string">{0}</item></content></resource>'.format(encoded_test_string)
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(file_name, xml_string)
#        zip1.close()
#        zip2 = ZipFile(zip_file_name, 'r')
#        self.assertEqual( rs, PackageManager().get_resource_from_zip(zip2, file_name, True))
#        zip2.close()
#        os.remove(zip_file_name)
#        
#    def test_get_resource_from_zip_case_2(self):
#        '''[manager] test get zip content with incorrectly serialised resources'''
#        test_string = "HELLO WORLD"
#        file_name = 'testfile'
#        zip_file_name = 'test.zip'
#        encoded_test_string = base64.encodestring(test_string)        
#        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><resources><content><item>{0}</item></content></resources>'.format(encoded_test_string)
##        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><root xmlns="http://yarra-project.com/element/"><content><item>{0}</item></content></root>'.format(encoded_test_string)
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(file_name, xml_string)
#        zip1.close()
#        zip2 = ZipFile(zip_file_name, 'r')
#        try:
#            bzc = PackageManager().get_resource_from_zip(zip2, file_name, True)
#            self.assertEqual(test_string, bzc)
#            self.fail('Content should not be successfully extracted')
#        except DeserialisationException:
#            assert True
#        finally:
#            zip2.close()
#            os.remove(zip_file_name) 
#
#    def test_get_package_case_1(self):
#        '''[manager] test get contents of package with yarra package from url'''
#        # create test data
#        zip_file_name = 'test.zip'
#        configuration_file_name = 'configuration.xml'
#        module1_file_name = 'module1.py'
#        module2_file_name = 'module2.py'
#        module1_contents = "Hello World1"
#        module2_contents = "Hello World2"
#        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource>
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{1}</item>
#                        <item key="package:startup" type="yarra:type/boolean">False</item>
#                    </dict>                             
#                </list>
#            </content>
#        </resource>'''.format(module1_file_name, module2_file_name)           
#        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><resource xmlns="http://yarra-project.com/element/"><content><item key="content" type="yarra:type/string">{0}</item></content></resource>'
#        rs_1 = Resource(configuration_content)
#        rs_2 = Resource()
#        rs_2.content = module1_contents
#        rs_3 = Resource()
#        rs_3.content = module2_contents              
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(configuration_file_name, rs_1.serialise())
#        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
#        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
#        zip1.close()
#        zip1 = None     
#        
#        # get contents  
#        package = PackageManager().get_package(package_url=zip_file_name)
#                      
#        self.assertTrue(rs_1 in package.contents)
#        self.assertTrue(rs_2 in package.contents)
#        self.assertTrue(rs_3 in package.contents)
#        os.remove(zip_file_name)
#
#    def test_get_package_case_2(self):
#        '''[manager] test get contents of package with yarra package from binary string'''
#        # create test data
#        zip_file_name = 'test.zip'
#        configuration_file_name = 'configuration.xml'
#        module1_file_name = 'module1.py'
#        module2_file_name = 'module2.py'
#        module1_contents = "Hello World1"
#        module2_contents = "Hello World2"
#        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource>
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{1}</item>
#                        <item key="package:startup" type="yarra:type/boolean">False</item>
#                    </dict>                             
#                </list>
#            </content>
#        </resource>'''.format(module1_file_name, module2_file_name)           
#        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><resource xmlns="http://yarra-project.com/element/"><content><item key="content" type="yarra:type/string">{0}</item></content></resource>'
#        rs_1 = Resource(configuration_content)
#        rs_2 = Resource()
#        rs_2.content = module1_contents
#        rs_3 = Resource()
#        rs_3.content = module2_contents              
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(configuration_file_name, rs_1.serialise())
#        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
#        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
#        zip1.close()
#        zip1 = None     
#        package_binary_contents = open(zip_file_name, 'rb').read()
#        # get contents  
#        package = PackageManager().get_package(package_binary_contents=package_binary_contents)
#                      
#        self.assertTrue(rs_1 in package.contents)
#        self.assertTrue(rs_2 in package.contents)
#        self.assertTrue(rs_3 in package.contents)
#        os.remove(zip_file_name)
#               
#    def test_get_package_case_3(self):
#        '''[manager] test get contents of package with a non package file'''
#        
#        # create bad test data. Yarra package should be a zip file
#        zip_file_name = 'test.zip'
#        file1 = open(zip_file_name, "wb")
#        file1.close()
#        file1 = None
#          
#        try:
#            # get contents
#            PackageManager().get_package(package_url=zip_file_name)
#            self.fail('Yarra package should not be parsed successfully')
#        except BadYarraPackageException:
#            assert True    
#            
#        os.remove(zip_file_name)
#            
#    def test_get_package_case_4(self):
#        '''[manager] test get contents of package with a bad yarra package'''
#        # create test data
#        zip_file_name = 'test.zip'
#        module1_file_name = 'module1.py'
#        module2_file_name = 'module2.py'
#        module1_contents = "Hello World1"
#        module2_contents = "Hello World2"
#        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root xmlns="http://yarra-project.com/element/"><content><item>{0}</item></content></root>'    
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
#        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
#        zip1.close()    
#        zip1 = None  
#        
#        try:
#            # get contents  
#            dict = PackageManager().get_package(package_url=zip_file_name)
#            self.fail('Yarra package should not be parsed successfully')            
#        except BadYarraPackageException:
#            assert True
#        os.remove(zip_file_name)            
#            
#    def test_get_distribution_case_1(self):
#        '''[manager] test get distribution loading two modules'''
#        # create test data
#        zip_file_name = 'test.yarra'
#        module1_name = 'moduleone'
#        module2_name = 'moduletwo'
#        module1_file_name = module1_name + '.py'
#        module2_file_name = module2_name + '.py'
#        module1_contents = """class TestClassA(object):
#    test_attrib_1 = 2"""
#        module2_contents = """class TestClassB(object):
#    test_attrib_1 = 'blah'"""
#        package_name = "testpackage"
#        distribution_name = "test_distribution"
#        distribution_file_name = distribution_name + ".xml"
#        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
#<distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
#    <name>default</name>
#    <package>
#        <name>{0}</name>
#        <location>{1}</location>            
#    </package>
#</distribution>'''.format(package_name, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name))
#        configuration_file_name = 'configuration.xml'
#        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource>
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{1}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>                             
#                </list>
#            </content>
#        </resource>'''.format(module1_file_name, module2_file_name)           
#        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><resource xmlns="http://yarra-project.com/element/"><content><item key="content" type="yarra:type/string">{0}</item></content></resource>'
#        rs_1 = Resource(configuration_content)
#        rs_2 = Resource()
#        rs_2.content = module1_contents
#        rs_3 = Resource()
#        rs_3.content = module2_contents                  
#        file = open(distribution_file_name, 'w')
#        file.write(distribution_xml)
#        file.close()
#        file = None
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(configuration_file_name, rs_1.serialise())
#        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
#        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
#        zip1.close()
#        zip1 = None
#        
#        distribution_contents = PackageManager().get_distribution('file:///{0}/'.format(os.getcwd()), distribution_name)
#        
#        os.remove(zip_file_name)
#        os.remove(distribution_file_name)
#
#        package = Package()
#        package.contents.append(rs_1)
#        package.contents.append(rs_2)
#        package.contents.append(rs_3)
#                              
#        if package == distribution_contents[0]:
#            assert True
#        else:
#            self.fail('failed')
#        
#    def test_get_distribution_case_2(self):
#        '''[manager] test get distribution loading one module only '''        
#        # create test data
#        zip_file_name1 = 'test1.yarra'
#        zip_file_name2 = 'test2.yarra'
#        module1_name = 'moduleone'
#        module2_name = 'moduletwo'
#        module1_file_name = module1_name + '.py'
#        module2_file_name = module2_name + '.py'
#        module1_contents = """class TestClassA(object):
#    test_attrib_1 = 2"""
#        module2_contents = """class TestClassB(object):
#    test_attrib_1 = 'blah'"""
#        package_name_1 = "testpackage1"
#        package_name_2 = "testpackage2"
#        distribution_name = "test_distribution"
#        distribution_file_name = distribution_name + ".xml"
#        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
#<distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
#    <name>default</name>
#    <package>
#        <name>{0}</name>
#        <location>{1}</location>            
#    </package>
#    <package>
#        <name>{2}</name>
#        <location>{3}</location>            
#    </package>
#</distribution>'''.format(package_name_1, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name1), 
#                          package_name_2, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name2))
#        configuration_file_name = 'configuration.xml'
#        configuration1_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource>
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>       
#                </list>
#            </content>
#        </resource>'''.format(module1_file_name)
#        configuration2_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource xmlns="http://yarra-project.com/element/">
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>                            
#                </list>
#            </content>
#        </resource>'''.format(module2_file_name)       
#        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><resource xmlns="http://yarra-project.com/element/"><content><item key="content" type="yarra:type/string">{0}</item></content></resource>'
#        rs_1 = Resource(configuration1_content)
#        rs_2 = Resource()
#        rs_2.content = module1_contents                
#        file = open(distribution_file_name, 'w')
#        file.write(distribution_xml)
#        file.close()
#        file = None
#        zip1 = ZipFile(zip_file_name1, 'w')
#        zip1.writestr(configuration_file_name, configuration1_content)
#        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
#        zip1.close()
#        zip1 = None
#
#        zip2 = ZipFile(zip_file_name2, 'w')
#        zip2.writestr(configuration_file_name, configuration2_content)
#        zip2.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
#        zip2.close()
#        zip2 = None        
#        
#        distribution_contents = PackageManager().get_distribution('file:///{0}/'.format(os.getcwd()), distribution_name, [package_name_1])
#        
#        os.remove(zip_file_name1)
#        os.remove(zip_file_name2)
#        os.remove(distribution_file_name)
#
#        package = Package()
#        package.contents.append(rs_1)
#        package.contents.append(rs_2)
#        
#        if package == distribution_contents[0]:
#            assert True
#        else:
#            self.fail('failed')                
#               
#    def test_install_distribution_case_1(self):
#        '''[manager] test install distribution two modules'''
#        # setup
#        original_database_name = database.DATABASE_NAME
#        temp_database_name = 'temp.db'
#        database.DATABASE_NAME = temp_database_name
#         
#        # create test data
#        zip_file_name = 'test.yarra'
#        module1_name = 'moduleone'
#        module2_name = 'moduletwo'
#        module1_file_name = module1_name + '.py'
#        module2_file_name = module2_name + '.py'
#        module1_contents = """class TestClassA(object):
#    test_attrib_1 = 2"""
#        module2_contents = """class TestClassB(object):
#    test_attrib_1 = 'blah'"""
#        package_name = "testpackage"
#        distribution_name = "test_distribution"
#        distribution_file_name = distribution_name + ".xml"
#        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
#<distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
#    <name>default</name>
#    <package>
#        <name>{0}</name>
#        <location>{1}</location>            
#    </package>
#</distribution>'''.format(package_name, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name))
#        configuration_file_name = 'configuration.xml'
#        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
#        <resource>
#            <content>
#                <list key="package:manifest/modules">
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{0}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>
#                    <dict>
#                        <item key="package:filename" type="yarra:type/string">{1}</item>
#                        <item key="package:startup" type="yarra:type/boolean">True</item>
#                    </dict>                             
#                </list>
#            </content>
#        </resource>'''.format(module1_file_name, module2_file_name)
#        rs_1 = Resource(serialised_object=configuration_content)
#        rs_1.set_metadata(Uri(manager.PACKAGE_PACKAGENAME), package_name)
#        rs_2 = Resource()
#        rs_2.content = base64.encodestring(module1_contents)
#        rs_2.set_metadata(Uri(manager.PACKAGE_PACKAGENAME), package_name)        
#        rs_2.set_metadata(Uri('package:modulename'), ".".join([package_name, module1_name]))
#        rs_3 = Resource()
#        rs_3.content = base64.encodestring(module2_contents)
#        rs_3.set_metadata(Uri(manager.PACKAGE_PACKAGENAME), package_name)        
#        rs_3.set_metadata(Uri('package:modulename'), ".".join([package_name, module2_name]))
#        file = open(distribution_file_name, 'w')
#        file.write(distribution_xml)
#        file.close()
#        file = None
#        zip1 = ZipFile(zip_file_name, 'w')
#        zip1.writestr(configuration_file_name, rs_1.serialise())
#        zip1.writestr(module1_file_name + ".xml", rs_2.serialise())
#        zip1.writestr(module2_file_name + ".xml", rs_3.serialise())
#        zip1.close()
#        zip1 = None
#        
#        ds = DataStore()
#        PackageManager().install_distribution(ds, 'file:///{0}/'.format(os.getcwd()), distribution_name)
#        
#        resources = ds.gets([1,2,3])
#
#        # remove test data
#        os.remove(zip_file_name)
#        os.remove(distribution_file_name)
#        os.remove(database.DATABASE_NAME)
#        
#        # restore original data
#        database.DATABASE_NAME = original_database_name
#        
#        # change test data to match data that is stored (i.e. non encoded content and ids set)        
#        rs_2.set_id(2)
#        rs_2.content = module1_contents
#        rs_3.set_id(3)
#        rs_3.content = module2_contents
#        
#        if rs_2 in resources and rs_3 in resources:
#            assert True              
#        else:
#            self.fail('failed')
#                
    
    def test(self):
        module1_contents = """class TestClassA(object):
    test_attrib_1 = 2"""
        module1_name = 'moduleone'
        package_name = "testpackage"
        rs_2 = Resource()
        rs_2.content = base64.encodestring(module1_contents)
        rs_2.set_metadata(Uri(manager.PACKAGE_PACKAGENAME), package_name)        
        rs_2.set_metadata(Uri('package:modulename', rs_2._ns), ".".join([package_name, module1_name]))
#        rs_2.set_metadata(Uri('package:modulename'), ".".join([package_name, module1_name]))
        rs_1 = Resource(serialised_object=rs_2.serialise())
        print rs_2
        print rs_1
        self.assertEqual(rs_2, rs_1)
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()